#pragma once
#include "EDAABB.h"
#include "matrix4.h"
#include <queue>

enum conditionID {PLAYERHURT, HASAMMO, GOTO, GUNLOADED, GUNAIMED, ISATAMMO, HASTARGET, NONE};

struct Condition
{
	conditionID ID;
	bool active;

	Condition(){}
	Condition(conditionID _id, bool _active = false){ID = _id; active = _active;}
	~Condition(){}
};




struct Action
{
	std::vector<Condition> pre;
	std::vector<Condition> post;

	float animationTime;
	char * name;
};

class CBrain
{
private:
	// neuralNetwork m_nn; // BRUHAHAHAHAHHAHHAHAHAHAHHAHAHHAHHAHA
	std::queue<Action> m_plan;
	std::vector<Action> availableActions; // once system is dynamic, these will be pointers to objects in a Master List.

	Action * m_pCurrentAction;

	SGKAgent * m_pOwner;

public:
	void Serve(SGKAgent * owner);

	CBrain();
	//~CBrain(){}
	bool formulatePlan(Condition * goal, bool val);

	void update(float dt);

	char * currentBehavior(void)
	{
		if (m_pCurrentAction)
		{
			return m_pCurrentAction->name;
		}
		else
		{
			return "[none]";
		}
	}
};

class SGKAgent
{
private:

	vec3f m_Center;
	float m_fRadius;
	GLUquadric * quad;
	matrix4d m_Matrix;
	vec3d m_Dest;
	CBrain m_Brain;

public:

	SGKAgent(void);

	//~SGKAgent(void);

	void Draw(void);

	// Takes in a string and a RELATIVE position.
	void DrawText(char * text, vec3f pos);

	void Init(void);

	void Kill(void);

	void Update(float dt);

public:

	//Accessors and Mutators
	const vec3f& GetCenter(void){ return m_Center; }

	const float GetRadius(void){ return m_fRadius; }

	inline void SetCenter(const vec3f& center) { m_Matrix.wx = center.x; m_Matrix.wy = center.y; m_Matrix.wz = center.z; }

	inline void SetCenter(const float fX, const float fY, const float fZ) { m_Matrix.wx = fX; m_Matrix.wy = fY; m_Matrix.wz = fZ; }

	inline void SetDestination(vec3f dest) {m_Dest.x = (double)dest.x; m_Dest.y = (double)dest.y; m_Dest.z = (double)dest.z;}

	inline void SetDestination(vec3d dest) {m_Dest = dest;}

	const vec3f GetDestination(void) {return m_Dest;}

	inline void SetRadius(const float fRadius) { m_fRadius = fRadius; }
};

